﻿namespace ModuleOne
{
    using System.Collections.Generic;
    using System.IO;

    using MEF_Test.Bricks;
    using MEF_Test.Contracts;

    using Microsoft.Practices.Unity;

    /// <summary>    
    /// This class is in charge of accessing the file itself : open, cache, retrieve the data : everyhing which is related to the file itself.
    /// It contains a reference to an *other* object, which implements IMediaFileHandler : this will be used to access the Media, not the file : 
    /// Length, artwork, provide a template, etc.
    /// The Classes implementing IMediaFileHandler might use other classes that could be switchable according to the codec used.
    /// for instance : an avi video file : 
    /// - LocalDiskMediaFileHandler would handle the file on the disk ( as any other filetypes )
    /// - An IMediaFileHandler implementing class would handle the .avi file types (container)
    /// - It might use a nested object to handle the video stream itself which would be different if the video stream is Divx, Xvid, multiple-audio, etc. but the use of this subclass is transparent for LocalDiskMediaFileHandler and therefore, not mandatory !
    /// </summary>
    public class LocalDiskFileHandler : IDiskFileHandler
    {        
        #region Constants and Fields

        /// <summary>
        /// a string identifying the media type within the file.
        /// </summary>
        private readonly string _contentType = string.Empty;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="LocalDiskFileHandler"/> class.
        /// </summary>
        /// <param name="path">The location of the file.</param>
        /// <param name="contentType">the media content-type.</param>
        internal LocalDiskFileHandler(string path, string contentType) 
        {
            Path = path;
            _contentType = contentType;
            if (File.GetAttributes(path).HasFlag(FileAttributes.Directory))
            {
                CanHaveChildren = true;
            }            
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets a value indicating whether this instance can have children.
        /// </summary>
        /// <value>
        /// <c>true</c> if this instance can have children; otherwise, <c>false</c>.
        /// </value>
        public bool CanHaveChildren { get; private set; }

        /// <summary>
        /// Gets the content-type : it is used to identify the type of file, and the container.       
        /// </summary>
        /// <remarks>the content-type is not supposed to identify the codec used within the container.</remarks>
        /// <example>audio/mp3 audio/ogg video/avi video/matroska video/quicktime</example>
        public string ContentType
        {
            get
            {
                return _contentType;
            }
        }

        /// <summary>
        /// Gets a <see cref="string"/> identifying the file.
        /// </summary>
        /// <value>The <see cref="string"/> identifying the file.</value>
        public string FileName
        {
            get
            {
                return System.IO.Path.GetFileName(this.Path);
            }
        }

        /// <summary>
        /// Gets a <see cref="string"/> identifying location of the file.
        /// </summary>
        /// <value>The <see cref="string"/> identifying the location of the file.</value>
        public string Path { get; private set; }

        #endregion

        #region Implemented Interfaces

        #region IFileHandler

        /// <summary>
        /// Gets the stream to read the file with read-write file sharing.
        /// </summary>
        /// <returns>A <see cref="FileStream"/> object with ReadWrite file sharing and Read file access.</returns>
        public Stream GetStream()
        {
            return File.Open(Path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
        }

        /// <summary>
        /// Gets the exported actions which are supported by the provided <see cref="IBrowserDetailViewModel"/> object.
        /// </summary>
        /// <param name="browserNodeBase">
        /// The browser node base.
        /// </param>
        /// <returns>The supported actions.</returns>
        public IEnumerable<INodeAction> GetSupportedActions(IBrowserNodeViewModel browserNodeBase)
        {
            // 1° Gets all the exported actions
            var v = new List<INodeAction>();
            var actionsManager = IoC.Current.Resolve<IActionsManager>();

            // for each exported actions : 
            foreach (var item in actionsManager.ExportedActions)
            {
                // 2° ... we check if the action supports the node.                
                var compatibleProviders = item.Value.GetCompatibleProviders(browserNodeBase);
                var selectedProvider = browserNodeBase.SelectProvider(compatibleProviders, item.Value);
                if (selectedProvider != null)
                {
                    v.Add(item.Value);
                }
            }

            return v;
        }

        #endregion

        #endregion

        #region Methods

        #endregion
    }
}
